/**
 * 多面柱体 - L5
 * @author lonphy
 * @version 0.1
 */
(function(L5) {
	"use strict";
	const BANDS = 10;
	class Cylinder {
		/**
		 * 平面构造
		 * @param radius {Number} 圆面半径
		 * @param height {Number} 圆柱长度
		 * @param rb {Number} 圆面切分段数
		 */
		constructor(radius, height, rb) {
			this.radius = radius || 1;
			this.height = height || 1;

			this.vertices = [];
			this.indices = [];
			this.materialLibrary = {};
			this.maters = [];

			this.rb = rb || BANDS;

			this.create();
		}

		/**
		 * 构造平面
		 */
		create() {
			var rb = this.rb,
				radius = this.radius,
				startZ = this.height/ 2,
				endZ = -startZ,
				maxStep = rb+ 1,
				angleStep = 2*Math.PI/maxStep,
				uvStep = 1/maxStep,
				ss = 2*(maxStep+1),
				bs = maxStep+ 1,
				front = [], back = [], side = [],
				frontIndices=[], backIndices=[], sideIndices=[],
				ca, asin,acos, a,rc,rs,a2;

			front.push(0,0,startZ);	// center pos
			front.push(0,0,-1);		// normal
			front.push(0.5,0.5, 0);		// uv

			back.push(0,0,endZ);	// center pos
			back.push(0,0,1);		// normal
			back.push(0.5,0.5, 0);		// uv

			for (a = 0; a < maxStep; ++a) {
				// 当前角度XY
				ca = a * angleStep;
				asin = Math.sin(ca);
				acos = Math.cos(ca);
				rc = radius*acos;
				rs = radius*asin;

				front.push(rc, rs, startZ);					// first pos
				front.push(0,0,-1);											// normal
				front.push(0.5 - 0.5*acos, 0.5-0.5*asin, 0);						// uv
				frontIndices.push(0, a+1, a+2);

				back.push(rc, rs, endZ);				// first pos
				back.push(0,0,1);											// normal
				back.push(0.5 - 0.5*acos, 0.5-0.5*asin, 0);						// uv
				backIndices.push(bs, bs+a+2, bs+a+1);

				side.push(rc, rs, startZ);
				side.push(acos, asin, 0);		// normal
				side.push(0, 1-a*uvStep, 0);		// uv

				side.push(rc, rs, endZ);
				side.push(acos, asin, 0);		// normal
				side.push(1, 1-a*uvStep, 0);		// uv
				a2 = 2*a;
				sideIndices.push(ss+a2, ss+1+a2, ss+3+a2);
				sideIndices.push(ss+a2, ss+3+a2, ss+2+a2);
			}

			frontIndices[frontIndices.length-1] = 1;
			backIndices[backIndices.length-2] = bs+1;

			sideIndices[sideIndices.length-1] = ss;
			sideIndices[sideIndices.length-2] = ss+1;
			sideIndices[sideIndices.length-4] = ss+1;


			this.vertices = front.concat(back).concat(side);
			this.indices = frontIndices.concat(backIndices).concat(sideIndices);
		}

		setMaterial(name, mater) {
			this.materialLibrary[name] = mater;
			this.maters.push(name);
		}

		getMesh() {
			return {
				vertices: this.vertices.slice(),
				indices: this.indices.slice(),
				materialLibrary: this.materialLibrary,
				maters: this.maters.slice(),
				hasIndex: true
			};
		}
	}

	L5.Geometry.Cylinder = Cylinder;
})(window.L5);